﻿using Email.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace Email.model
{
    public struct MessageHead
    {
        public string From { get; set; }
        public string To { get; set; }
        public string Subject { get; set; }
        public string Date { get; set; }
    }
    internal class MailManger
    {
        private string Server = "pop.qq.com";
        private int Port = 995; // SSL默认端口
        private string Username;
        private string Password;
        private string emailDirectory; // 新增的字段

        private TcpClient client;
        private SslStream sslStream;
        private StreamReader reader;
        private StreamWriter writer;
        private UserManager userManager; // 添加对 UserManager 的引用，为了删除失效的smtp授权码

        // 是否成功连接
        private bool isConnected = false;
        // 所有邮件的头部信息
        public List<MessageHead> messageHeads = new List<MessageHead>();
        // 所有邮件数量
        private int MessageNum = 0;
        private static string basepath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "data", "emails"));

        public MailManger(string Username, string Password)
        {
            this.Username = Username;
            this.Password = Password;
            this.userManager = new UserManager(); // 初始化 UserManager
            string user = Username.Replace("@qq.com", "qq");
            emailDirectory = Path.Combine(basepath, user);

            if (!Directory.Exists(emailDirectory))
            {
                Directory.CreateDirectory(emailDirectory);
            }
        }


        private void SendCommand(string command)
        {
            writer.WriteLine(command);
            writer.Flush();
        }

        // 建立连接
        public void Connect()
        {
            try
            {
                client = new TcpClient(Server, Port);
                sslStream = new SslStream(client.GetStream());
                sslStream.AuthenticateAsClient(Server);

                reader = new StreamReader(sslStream, Encoding.ASCII);
                writer = new StreamWriter(sslStream, Encoding.ASCII) { AutoFlush = true };

                // 读取服务器欢迎消息
                reader.ReadLine();

                // 发送USER命令
                SendCommand($"USER {Username}");
                reader.ReadLine();

                // 发送PASS命令
                SendCommand($"PASS {Password}");
                reader.ReadLine();
                // Console.WriteLine("连接成功并验证通过");

                isConnected = true;
            }
            catch (Exception ex)
            {
                // Console.WriteLine($"连接失败: {ex.Message}");
                isConnected = false;
                // 在连接失败时删除SMTP授权码的记录
                userManager.DeleteSmtpAuthCode(Username); // 在这里添加这一行
            }
        }


        // 打开邮件
        public void Open(int messageNumber)
        {
            if (!isConnected)
            {
                return;
            }
            try
            {
                if (writer == null || reader == null)
                {
                    throw new InvalidOperationException("连接尚未建立。请先调用Connect方法。");
                }

                SendCommand($"RETR {messageNumber}");
                string response = reader.ReadLine();

                if (!response.StartsWith("+OK"))
                {
                    throw new Exception("服务器响应失败");
                }

                StringBuilder emailContent = new StringBuilder();
                string line;
                string rawEmailsDirectory = Path.Combine(emailDirectory, "raw_emails");

                if (!Directory.Exists(rawEmailsDirectory))
                {
                    Directory.CreateDirectory(rawEmailsDirectory);
                }

                string filePath = Path.Combine(rawEmailsDirectory, $"raw_email{messageNumber}.txt");

                if (!File.Exists(filePath)) // 检查文件是否存在
                {
                    using (StreamWriter filewriter = new StreamWriter(filePath))
                    {
                        while ((line = reader.ReadLine()) != ".")
                        {
                            filewriter.WriteLine(line);
                            emailContent.AppendLine(line);
                        }
                    }

                    MessageHead messageHead = new MessageHead();
                    GetHeadInfo(emailContent.ToString(), ref messageHead);
                    this.messageHeads.Add(messageHead);

                    string boundary = GetBoundary(emailContent.ToString());

                    string overripeEmailsDirectory = Path.Combine(emailDirectory, "overripe_emails");

                    if (!Directory.Exists(overripeEmailsDirectory))
                    {
                        Directory.CreateDirectory(overripeEmailsDirectory);
                    }

                    string overripePath = Path.Combine(overripeEmailsDirectory, $"overripe_email{messageNumber}.txt");

                    using (StreamWriter filewriter = new StreamWriter(overripePath))
                    {
                        foreach (string str in GetBodyInfo(emailContent.ToString(), "--" + boundary))
                        {
                            string decode_line = DecodeBase64(str);
                            filewriter.WriteLine(decode_line);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Console.WriteLine($"获取邮件内容失败: {ex.Message}");
            }
        }

        // 实现List
        public void List()
        {
            // Console.WriteLine("进入list");
            if (!isConnected)
            {
                return;
            }
            try
            {
                // 发送LIST命令
                SendCommand("LIST");
                string response = reader.ReadLine();
                Console.WriteLine(response);

                // 检查服务器响应
                if (!response.StartsWith("+OK"))
                {
                    throw new Exception("服务器响应失败");
                }

                // 读取邮件列表
                string line;
                while ((line = reader.ReadLine()) != ".")
                {
                    Console.WriteLine(line);
                    this.MessageNum++;
                }

                for (int i = 0; i < MessageNum; i++)
                {
                    Open(i + 1);
                }
            }
            catch (Exception ex)
            {
                MessageNum = 0;
                Console.WriteLine($"获取邮件列表失败: {ex.Message}");
            }
        }

        public void Delete(int emailIndex)
        {
            Connect();
            if (!isConnected)
            {
                return;
            }
            SendCommand($"DELE {emailIndex}");
            string response = reader.ReadLine();

            if (!response.StartsWith("+OK"))
            {
                throw new InvalidOperationException($"Error deleting email at index {emailIndex}: {response}");
            }
            Disconnect();
        }
        public void Disconnect()
        {
            if (writer != null)
            {
                SendCommand("QUIT");
            }

            reader?.Close();
            writer?.Close();
            sslStream?.Close();
            client?.Close();

            isConnected = false;
            //MessageNum = 0;
            //messageHeads.Clear();

        }
        // 解析邮件

        // 解码提取后的base64
        private static string DecodeBase64(string encodedData)
        {
            try
            {
                // 将 Base64 字符串解码为字节数组
                byte[] data = Convert.FromBase64String(encodedData);

                // 将字节数组转换为 UTF-8 编码的字符串
                string decodedString = Encoding.UTF8.GetString(data);

                return decodedString;
            }
            catch (FormatException e)
            {
                // Console.WriteLine($"Invalid Base64 string: {e.Message}");
                return null;
            }
        }
        // 解码Header的Base64，但是存在混合情况
        private static string DecodeBase64String(string input)
        {
            // 正则表达式匹配Base64编码的内容
            string pattern = @"=\?utf-8\?B\?(.*?)\?=";
            return Regex.Replace(input, pattern, match =>
            {
                string base64Content = match.Groups[1].Value;
                byte[] data = Convert.FromBase64String(base64Content);
                return Encoding.UTF8.GetString(data);
            });
        }
        // 提取头部重要字段
        private static string ExtractHeaderField(string emailContent, string fieldName)
        {
            // Pattern to match both Base64 encoded and plain text content
            string pattern = $@"^{fieldName}:\s*(=\?utf-8\?B\?(.*?)\?=|.*)";
            Match match = Regex.Match(emailContent, pattern, RegexOptions.Multiline | RegexOptions.IgnoreCase);

            if (match.Success)
            {
                string fieldValue = match.Groups[2].Success ? match.Groups[2].Value : match.Groups[1].Value;
                return match.Groups[2].Success ? DecodeBase64(fieldValue) : fieldValue.Trim();
            }

            return string.Empty;
        }
        // 获取头部信息
        private static void GetHeadInfo(string emailContent, ref MessageHead mh)
        {
            string from = ExtractHeaderField(emailContent, "From");
            string to = ExtractHeaderField(emailContent, "To");
            string subject = ExtractHeaderField(emailContent, "Subject");
            string Date = ExtractHeaderField(emailContent, "Date");

            mh.From = from;
            mh.To = to;
            mh.Subject = subject;
            mh.Date = Date;
        }
        //寻找正文界定符
        private static string GetBoundary(string input)
        {
            string pattern = @"boundary=""([^""]*)""";
            Match match = Regex.Match(input, pattern);

            if (match.Success && match.Groups.Count > 1)
            {
                return match.Groups[1].Value;
            }

            return string.Empty;
        }


        // 提取正文base64编码字符串
        private static List<string> GetBodyInfo(string input, string endString)
        {
            List<string> results = new List<string>();
            string pattern = $@"Content-Transfer-Encoding: base64\s*(.*?)(?:{Regex.Escape(endString)}|\r?\n\r?\n|$)";
            MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.Singleline);

            foreach (Match match in matches)
            {
                if (match.Groups.Count > 1)
                {
                    results.Add(match.Groups[1].Value.Trim());
                }
            }

            return results;
        }

        public void MessageHeadInit()
        {
            MessageNum = 0;
            messageHeads.Clear();
            Connect();
            List();
            Disconnect();
        }

    }
}
